//////////////////////////////////////////////////////////////////////////////////////////////////////
// 项目名   : Container
// 文件名   : Variant.h
// 作者     : Aiye
// 日期     : 2025/9/8 11:56
// 邮箱     : 2878548868@qq.com
// 摘要     : 介绍Variant
//////////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef CONTAINER_VARIANT_H
#define CONTAINER_VARIANT_H
#include <iostream>
#include <string>
#include <variant>

/**
 * @brief 类型安全的联合体，可以储存多种类型中的一种
 */
class Variant
{
public:
    Variant()
    {
        std::variant<int , double , std::string> var; // 只能储存一个值，新值会被旧值覆盖
        var = 3.14; // 储存double
        var = "Hello"; // 储存std::string
        var = 42 ; // 储存int

        // 访问variant
        // 1. 使用std::get（必须知道当前类型）
        try
        {
            auto nVar = std::get<int>(var);
            std::cout << "int: " << nVar << std::endl;
        } catch (const std::bad_variant_access& e)
        {
            std::cout << "Not an int" << std::endl;
        }

        // 2. 使用std::get_if（安全访问）
        if (auto ptr = std::get_if<int>(var))
        {
            std::cout << "int:" << *ptr << std::endl;
        }

        // 3. 使用std::visit（访问所有可能类型）
        std::visit([]<typename T0>(T0&& arg)
        {
            using T = std::decay_t<T0>; // 去除cv修饰符

            // 静态类型判断
            if constexpr (std::is_same_v<T, int>)
            {
                std::cout << "int: " << arg << std::endl;
            }
            else if constexpr (std::is_same_v<T, double>)
            {
                std::cout << "double: " << arg << std::endl;
            }
            else if constexpr (std::is_same_v<T, std::string>)
            {
                std::cout << "string: " << arg << std::endl;
            }
        }, var);

        // 获取当前存储类型的索引
        std::cout << "Index: " << var.index() << std::endl;

        // 检查是否持有特定类型
        if (std::holds_alternative<int>(var))
        {
            std::cout << "Holds int" << std::endl;
        }
    }
};
#endif //CONTAINER_VARIANT_H